package com.hmdp.aspect;

import cn.hutool.core.lang.UUID;
import com.hmdp.annotion.ReliableMessage;
import com.hmdp.entity.MessageRecord;
import com.hmdp.entity.MessageStatus;
import com.hmdp.service.MessageRecordService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.lang.reflect.Method;

@Aspect
@Component
@Slf4j
public class ReliableMessageAspect {

    @Autowired
    private MessageRecordService messageRecordService;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    @Around("@annotation(reliableMessage)")
    public Object around(ProceedingJoinPoint joinPoint, ReliableMessage reliableMessage) throws Throwable {
        // 1. 执行业务方法
        Object result = joinPoint.proceed();
        
        // 2. 记录消息
        String messageId = generateMessageId();
        String paramsJson = objectMapper.writeValueAsString(joinPoint.getArgs());
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        
        MessageRecord messageRecord = new MessageRecord();
        messageRecord.setMessageId(messageId);
        messageRecord.setServiceName(reliableMessage.serviceName());
        messageRecord.setMethodName(reliableMessage.methodName());
        messageRecord.setParamsJson(paramsJson);
        messageRecord.setStatus(MessageStatus.PENDING.getCode());
        messageRecord.setRetryCount(0);
        messageRecord.setClassName(method.getDeclaringClass().getName());
        messageRecord.setOriginalMethodName(method.getName());
        
        messageRecordService.save(messageRecord);
        
        // 3. 异步尝试调用其他服务
        try {
            sendMessage(messageRecord, reliableMessage);
        } catch (Exception e) {
            // 发送失败将由定时任务重试
            log.error("首次发送消息失败，messageId: {}", messageId, e);
        }
        
        return result;
    }
    
    private void sendMessage(MessageRecord messageRecord, ReliableMessage reliableMessage) {
        // 实现调用远程服务的逻辑
        boolean success = remoteCall(
            messageRecord.getServiceName(), 
            messageRecord.getMethodName(), 
            messageRecord.getParamsJson()
        );
        
        if (success) {
            messageRecordService.updateStatus(messageRecord.getMessageId(), MessageStatus.SUCCESS);
        } else {
            messageRecordService.updateStatus(messageRecord.getMessageId(), MessageStatus.FAILED);
        }
    }
    
    private String generateMessageId() {
        return UUID.randomUUID().toString().replace("-", "");
    }
    
    // 模拟远程调用
    private boolean remoteCall(String serviceName, String methodName, String paramsJson) {
        // 实际项目中可以使用Feign或其他RPC框架
        // 这里简化为随机成功/失败
        return Math.random() > 0.3; // 70%成功率
    }
}